package com.cdks.wuxiu.api.service;

import com.cdks.wuxiu.api.component.constant.Constant;
import com.cdks.wuxiu.api.model.dto.UserScoreDTO;
import com.cdks.wuxiu.api.service.mysql.UserBaseInfoService;
import com.cdks.wuxiu.api.service.mysql.UserBillInfoService;
import com.cdks.wuxiu.api.service.mysql.UserScoreInfoService;
import com.cdks.wuxiu.api.service.mysql.UserWalletInfoService;
import com.cdks.wuxiu.api.service.mysql.WithdrawAccountInfoService;
import com.cdks.wuxiu.api.service.mysql.WithdrawMoneyConfigService;
import com.cdks.wuxiu.api.service.mysql.WithdrawOrderInfoService;
import com.cdks.wuxiu.api.service.mysql.WithdrawRatioConfigService;
import com.cdks.wuxiu.api.util.SmsUtils;
import com.cdks.wuxiu.api.util.TimeUtils;
import com.cdks.wuxiu.common.exception.ApiException;
import com.cdks.wuxiu.entity.mysql.UserBaseInfo;
import com.cdks.wuxiu.entity.mysql.UserWalletInfo;
import com.cdks.wuxiu.entity.mysql.WithdrawAccountInfo;
import com.cdks.wuxiu.entity.mysql.WithdrawMoneyConfig;
import com.cdks.wuxiu.entity.mysql.WithdrawOrderInfo;
import com.cdks.wuxiu.entity.mysql.WithdrawRatioConfig;

import lombok.extern.slf4j.Slf4j;

import java.util.List;
import javax.annotation.Resource;

import org.springframework.stereotype.Service;


/**
 * 提现服务实现类
 */
@Slf4j
@Service
public class WithdrawServiceImpl implements WithdrawService {
    @Resource
    private WithdrawAccountInfoService withdrawAccountInfoService;
    @Resource
    private WithdrawOrderInfoService withdrawOrderInfoService;
    @Resource
    private WithdrawRatioConfigService withdrawRatioConfigService;
    @Resource
    private WithdrawMoneyConfigService withdrawMoneyConfigService;           
    @Resource
    private UserWalletInfoService userWalletInfoService;    
    @Resource
    private UserScoreInfoService userScoreInfoService;
    @Resource
    private UserBaseInfoService userBaseInfoService;
    @Resource
    private UserBillInfoService userBillInfoService;
    

    @Override
    public int addAccount(WithdrawAccountInfo account) {
        boolean ret  = withdrawAccountInfoService.save(account);
        if (ret == false)
        {
            return -1;
        }

        return 0;
    }

    @Override
    public int delAccount(long userId, long acctId) {
        int ret  = withdrawAccountInfoService.delAccount(userId, acctId);
        if (ret < 0)
        {
            return -1;
        }

        return 0;
    }
    
    @Override
    public List<WithdrawAccountInfo> getAccountList(long userId, List<Integer> types) {
        return withdrawAccountInfoService.getByUserIdWithType(userId, types);
    }

    @Override
    public List<WithdrawRatioConfig> getWithdrawType() {
        return withdrawRatioConfigService.getValidConfig();
    }

    @Override
    public WithdrawRatioConfig getWithdrawRatio(UserBaseInfo userInfo, long acctId) {
        WithdrawAccountInfo account  = withdrawAccountInfoService.getByUserId(userInfo.getUserId(), acctId);
        if (account == null)
        {
            return null;
        }

        return withdrawRatioConfigService.getByAuthWithType(userInfo.getAuthLevel(), account.getType());
    }

    @Override
    public List<WithdrawMoneyConfig> getWithdrawMoneyListByType(int type) {
        return withdrawMoneyConfigService.getValidListByType(type);
    }

    @Override
    public WithdrawMoneyConfig getWithdrawFeeByMoney(int type, int money) {
        return withdrawMoneyConfigService.getByMoneyWithType(money, type);
    }

    @Override
    public int checkUserStatus(long userId) {
        WithdrawOrderInfo orderInfo  = withdrawOrderInfoService.getLastValid(userId);
        if (orderInfo != null)
        {
            if (orderInfo.getStatus() == Constant.AUDIT_STATUS_WAIT)
            {
                throw new ApiException(10, "提现失败，您有待审核提现订单");
            }

            if ((TimeUtils.getTimeSecond() - orderInfo.getCreateTime()) < Constant.TIME_VALUE_24_HOURS)
            {
                throw new ApiException(10, "提现失败，您距离上次提现未满24小时");
            }
        }

        return 0;
    }

    @Override
    public int createOrder(WithdrawOrderInfo order, long coin) {
        long ret;
        long costCoin;
        long costScore;
        long now  = TimeUtils.getTimeSecond();


        UserWalletInfo wallet  = userWalletInfoService.getByUserId(order.getUserId());
        log.info("withdraw createOrder: coin=" + coin + ", wallet=" + wallet);
        if (wallet.getCoin() < coin)
        {
            costCoin   = wallet.getCoin();
            costScore  = coin - wallet.getCoin();
        }
        else
        {
            costCoin   = coin;
            costScore  = 0;
        }

        //查询用户可用积分信息
        UserScoreDTO score  = userScoreInfoService.getBalanceByUser(order.getUserId(), now);
        log.info("withdraw createOrder: costCoin=" + costCoin + ", costScore=" + costScore + ", order=" + order + ", score=" + score);
        if (score.getScore() < costScore)
        {
            throw new ApiException(10, "提现失败，可提现余额不足");
        }

        //先扣金币
        if (costCoin > 0)
        {
            ret  = userWalletInfoService.decCoin(order.getUserId(), costCoin, Constant.STATIS_TYPE_WITHDRAW, Constant.PAY_MODE_FIRST);
            if (ret < 0)
            {
                SmsUtils.sendManageNotice("提现异常");
                log.error("update coin failed: userId=" + order.getUserId() + ", costCoin=" + costCoin + ", ret=" + ret);

                throw new ApiException(10, "提现失败，可提现余额不足");
            }
        }

        //再扣积分
        if (costScore > 0)
        {
            ret  = userScoreInfoService.decByUserId(order.getUserId(), score.getMinId(), score.getMaxId(), costScore, now);
            if (ret < 0)
            {
                SmsUtils.sendManageNotice("提现异常");
                log.error("update score failed : userId=" + order.getUserId() + ", score=" + costScore + ", ret=" + ret);

                return -1;
            }
            else
            {
                //扣除的积分写入账单
                ret  = userBillInfoService.saveBill(costScore, costScore, 0, costScore, costScore, order.getUserId(), Constant.USERID_SYSTEM, Constant.COST_TYPE_SCORE, Constant.COST_TYPE_SCORE, order.getId(), "提现");
                if (ret < 0)
                {
                    log.error("withdraw save bill failed: userId=" + order.getUserId() + ", score=" + costScore + ", ret=" + ret);
                }
            }
        }

        order.setCoin(costCoin);
        order.setScore(costScore);
        order.setCreateTime(TimeUtils.getTimeSecond());
        order.setOrderNo("WXD" + TimeUtils.getLocalDateTime("yyyyMMddHHmmssSSS") + order.getUserId());
        withdrawOrderInfoService.save(order);

        return 0;
    }

    @Override
    public List<WithdrawOrderInfo> getRecord(long userId, int page, long start, long stop) {
        return withdrawOrderInfoService.getRecord(userId, page, start, stop);
    }
}
